package com.neusoft.neuiotms.dcam.task;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neusoft.bizcore.web.dto.result.ResultListDTO;
import com.neusoft.bizcore.web.support.QueryOperator;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.common.constant.AHConstants;
import com.neusoft.neuiotms.dcam.constant.DCAMConsts;
import com.neusoft.neuiotms.dcam.fixed.dto.AssetDTO;
import com.neusoft.neuiotms.dcam.fixed.model.AssetType;
import com.neusoft.neuiotms.dcam.fixed.model.StockWarning;
import com.neusoft.neuiotms.dcam.fixed.repository.StockWarningRepository;
import com.neusoft.neuiotms.dcam.fixed.service.AssetService;
import com.neusoft.neuiotms.dcam.fixed.util.SendingMessage;
import com.neusoft.neuiotms.micro.auth.AuthMicroService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class StockWarningJob extends QuartzJobBean {

    @Autowired
    private AssetService assetService;

    @Autowired
    private StockWarningRepository stockWarningRepository;

    @Autowired
    private AuthMicroService authMicroService;

    @Autowired
    private SendingMessage sendingMessage;

    @Override
    protected void executeInternal(final JobExecutionContext context) throws JobExecutionException {
        StockWarningJob.log.info("库存预警提醒定时任务开始-----------------------");
        //所有的到期提醒
        final List<StockWarning> lists = this.stockWarningRepository.findAll();

        if (lists.isEmpty()) {
            StockWarningJob.log.info("当前无库存预警提醒设置");
            return;
        }
        final String title = "库存预警提醒";
        lists.forEach(reminder -> {
            final Searchable searchable = new Searchable();
            final List<String> typeCodes =
                    reminder.getAssetTypes().stream().map(AssetType::getCode).collect(Collectors.toList());
            searchable.put("smallTypeCodes", typeCodes);//类型code
            searchable.put("amount", reminder.getAmount(), QueryOperator.lte);
            final Page<AssetDTO> assets = this.assetService.search(Pageable.unpaged(), searchable);
            //            final Map<String, String> assetMap = new HashMap<>();
            //            assets.stream().collect(Collectors.toMap(AssetDTO::getSmallTypeCode, AssetDTO::getSmallTypeName));
            if (assets.getTotalElements() > 0) {
                final List<String> usernames = new ArrayList<>();
                final Map<String, Object> search = new HashMap<>();
                search.put("s_roleCode", AHConstants.ROLE_SL_ASSET_OWNER_ADMIN);
                final ResultListDTO<Map<String, Object>> userList = this.authMicroService.userIndex(search);
                userList.getData().stream().map(l -> l.get("username").toString()).filter(s -> null != s).distinct()
                        .forEach(usernames::add);

                final StringBuffer content = new StringBuffer("您有消耗品库存数量不足,以下这几种类型：");
                final String noticeType = reminder.getNoticeType();
                final String[] noticeTypes = noticeType.split(DCAMConsts.COMMA_SPILT);
                final List<String> noticeTypeList = new ArrayList<>(Arrays.asList(noticeTypes));
                //拼消息体
                final JSONObject notice = new JSONObject();
                notice.put("appCode", "dcam");
                notice.put("type", noticeTypeList);
                notice.put("title", title);
                if (noticeTypeList.contains(DCAMConsts.INFORM_TYPE_NOTICE)) {
                    final JSONObject system = new JSONObject();
                    system.put("noticeType", "库存预警");
                    system.put("noticeRoute", "standingbook_sl_consuptions");
                    final JSONArray userId = new JSONArray();
                    usernames.forEach(t -> {
                        userId.add(t);
                    });
                    system.put("users", userId);
                    final List<String> typeNames = assets.getContent().stream().map(s -> s.getSmallTypeName())
                            .distinct().collect(Collectors.toList());
                    //                    final Iterator<Entry<String, String>> iterator = assetMap.entrySet().iterator();
                    //                    while (iterator.hasNext()) {
                    //                        final Entry<String, String> entry = iterator.next();
                    //                        content.append(" ," + entry.getValue());
                    //                    }
                    content.append(String.join(",", typeNames));
                    system.put("content", content.toString());
                    final JSONObject info = new JSONObject();
                    final List<String> assetTypeCodes =
                            reminder.getAssetTypes().stream().map(AssetType::getCode).collect(Collectors.toList());
                    if ((assetTypeCodes != null) && !assetTypeCodes.isEmpty()) {
                        final StringBuffer buffertype = new StringBuffer();
                        assetTypeCodes.forEach(t -> {
                            buffertype.append(t.trim() + DCAMConsts.COMMA_SPILT);
                        });
                        info.put("s_asstTypeCodes", buffertype.toString());
                    }
                    system.put("businessInfo", info.toString());
                    notice.put("system", system);
                }
                if (noticeTypeList.contains(DCAMConsts.INFORM_TYPE_MAIL)) {
                    final JSONObject templateMsg = new JSONObject();
                    templateMsg.put("content", content.toString());
                    final JSONObject mail = new JSONObject();
                    mail.put("emailAddress", this.getUserMails(usernames));
                    mail.put("templateName", "noticeMail.ftl");
                    mail.put("templateMsg", templateMsg.toString());
                    notice.put("mail", mail);
                }
                this.sendingMessage.SendMsgToNotice(notice.toString());
                StockWarningJob.log.info("发送的消息内容是： " + notice.toString());
            }
        });
        StockWarningJob.log.info("库存预警提醒定时任务完成");
    }

    private String getUserMails(final List<String> usernames) {
        final StringBuffer strBuffer = new StringBuffer();
        final Map<String, String[]> params = new HashMap<>();

        params.put("usernames", usernames.toArray(new String[1]));
        final ResultListDTO<Map<String, Object>> result = this.authMicroService.batchusers(params);
        if (result.isSuccess()) {
            final List<Map<String, Object>> map = result.getData();
            map.forEach(t -> {
                if (t.get("mail") != null) {
                    strBuffer.append(t.get("mail").toString().trim() + ",");
                }
            });
        }
        return strBuffer.toString();

    }
}
